package com.chart.web.controller.system;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chart.common.core.controller.BaseController;
import com.chart.common.core.domain.AjaxResult;
import com.chart.common.core.domain.entity.SysUser;
import com.chart.common.core.redis.RedisCache;
import com.chart.common.utils.SecurityUtils;
import com.chart.common.utils.sms.SmsSendUtils;
import com.chart.system.domain.RegistrationChannels;
import com.chart.system.service.ISysUserService;
import com.chart.system.service.IUserCoinLogsService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * 注册验证
 *
 * @author chart
 */
@RestController
public class SysRegisterController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(SysRegisterController.class);
    //全球手机号正则表达式
    private static final String PHONE_NUMBER_REGEX = "^(?:\\+?(\\d{1,3}))?[-. (]*(\\d{1,4})?[-. )]*(\\d{1,4})?[-. ]*(\\d{1,4})?[-. ]*(\\d{1,9})?$";

    @Autowired
    private RedisCache redisCache;


    @Autowired
    private ISysUserService userService;


    public static final String qcode = "手机号：";


    /**
     * 新增用户
     * PC端
     */
    @ApiOperation("用户注册")
    @PostMapping("/register")
    @Transactional
    public AjaxResult register(@Validated @RequestBody SysUser user) {
        String phonenumber = user.getPhonenumber();
        // 手机号码格式验证
        if (!phonenumber.matches(PHONE_NUMBER_REGEX)) {
            log.error("手机号：{}格式不正确", phonenumber);
            return AjaxResult.error("手机号码格式不正确");
        }

        //用户数据验证
        if (ObjectUtils.isNotEmpty(user.getPhonenumber())) {
            //查询之前检查数据的一致性
            long count = userService.count(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, user.getPhonenumber()));
            if (count > 1) {
                log.error("在数据库中找到了多条手机号：{}", user.getPhonenumber());
                throw new IllegalStateException("手机号码不唯一，找到了多条记录");
            }

            SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, user.getPhonenumber()));
            if (ObjectUtils.isNotEmpty(sysUser)) {
                log.info("用户：{}手机号码：{}已存在", sysUser, user.getPhonenumber());
                return AjaxResult.error("用户'" + user.getPhonenumber() + "'注册失败，手机号码已存在");
            }
            //验证码验证
            String code = redisCache.getCacheObject(qcode + user.getPhonenumber()).toString();
            if (ObjectUtils.isNotEmpty(code) || user.getCode() != "0000") {
                if (!code.equals(user.getCode())) {
                    log.info("用户:{} 验证码：{}错误", sysUser, code);
                    return AjaxResult.error("验证码错误");
                }
            }
        }
        //邮箱唯一验证
        if (ObjectUtils.isNotEmpty(user.getEmail())) {
            SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, user.getEmail()));
            if (ObjectUtils.isNotEmpty(sysUser)) {
                return AjaxResult.error("用户'" + user.getPhonenumber() + "'注册失败，邮箱账号已存在");
            }
        }

        user.setNickName(user.getNickName());
        user.setUserName(user.getPhonenumber());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setRoleIds(new Long[]{2L});
        user.setDeptId(105L);//
        user.setHasComplete(0); //0：未完善  1：已完善
        user.setHasLoggedIn(0);
        user.setIsBind(0);
        if (user.getPlatform() == null) {
            user.setPlatform(1);
        } else {
            user.setPlatform(user.getPlatform()); //0:手机注册 1：电脑注册
        }

        try {
            boolean b = userService.insertUser(user);
            if (b) {
                log.info("用户：{}注册成功", user.getPhonenumber());
                return AjaxResult.success();
            } else {
                log.warn("用户：{}注册失败，未知原因", user.getPhonenumber());
                throw new RuntimeException("用户注册失败，未知原因");
            }
        } catch (Exception e) {
            log.error("用户：{}注册失败：{}", user.getPhonenumber(), e.getMessage());
            throw new RuntimeException(e);
        }

    }



    /**
     * H5
     * @param user
     * @return
     */
/*
    @ApiOperation("用户注册")
    @PostMapping("/registerH5")
    @Transactional
    public AjaxResult registerH5(@Validated @RequestBody SysUser user) {
        String phonenumber = user.getPhonenumber();
        // 手机号码格式验证
        if (!phonenumber.matches(PHONE_NUMBER_REGEX)) {
            log.error("手机号：{}格式不正确", phonenumber);
            return AjaxResult.error("手机号码格式不正确");
        }

        //用户数据验证
        if (ObjectUtils.isNotEmpty(user.getPhonenumber())) {
            //查询之前检查数据的一致性
            long count = userService.count(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, user.getPhonenumber()));
            if (count > 1) {
                log.error("在数据库中找到了多条手机号：{}", user.getPhonenumber());
                throw new IllegalStateException("手机号码不唯一，找到了多条记录");
            }

            SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, user.getPhonenumber()));
            if (ObjectUtils.isNotEmpty(sysUser)) {
                log.info("用户：{}手机号码：{}已存在", sysUser, user.getPhonenumber());
                return AjaxResult.error("用户'" + user.getPhonenumber() + "'注册失败，手机号码已存在");
            }
            //验证码验证
            String code = redisCache.getCacheObject(qcode + user.getPhonenumber()).toString();
            if (ObjectUtils.isNotEmpty(code) || user.getCode() != "0000") {
                if (!code.equals(user.getCode())) {
                    log.info("用户:{} 验证码：{}错误", sysUser, code);
                    return AjaxResult.error("验证码错误");
                }
            }
        }
        //邮箱唯一验证
        if (ObjectUtils.isNotEmpty(user.getEmail())) {
            SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, user.getEmail()));
            if (ObjectUtils.isNotEmpty(sysUser)) {
                return AjaxResult.error("用户'" + user.getPhonenumber() + "'注册失败，邮箱账号已存在");
            }
        }



        user.setNickName(user.getNickName());
        user.setUserName(user.getPhonenumber());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setRoleIds(new Long[]{2L});
        user.setDeptId(105L);//
        user.setHasComplete(0); //0：未完善  1：已完善
        user.setHasLoggedIn(0);
        user.setIsBind(0);



        String openId = user.getOpenId();
        String ticket = user.getTicket();


        if (user.getPlatform() == null) {
            user.setPlatform(1);
        } else {
            user.setPlatform(user.getPlatform()); //0:手机注册 1：电脑注册
        }


        try {
            boolean b = userService.insertUser(user);
            if (b) {
                log.info("用户：{}注册成功", user.getPhonenumber());
                redisCache.setCacheObject(ticket, "login_" + openId, 180, TimeUnit.SECONDS);
                return AjaxResult.success();
            } else {
                log.warn("用户：{}注册失败，未知原因", user.getPhonenumber());
                throw new RuntimeException("用户注册失败，未知原因");
            }
        } catch (Exception e) {
            log.error("用户：{}注册失败：{}", user.getPhonenumber(), e.getMessage());
            throw new RuntimeException(e);
        }

    }
*/


    /**
     * H5
     * @param user
     * @return
     */
    /**
     * H5
     * @param user
     * @return
     */
    @ApiOperation("用户注册")
    @PostMapping("/registerH5")
    @Transactional
    public AjaxResult registerH5(@Validated @RequestBody SysUser user) {
        String phonenumber = user.getPhonenumber();
        // 手机号码格式验证
        if (!phonenumber.matches(PHONE_NUMBER_REGEX)) {
            log.error("手机号：{}格式不正确", phonenumber);
            return AjaxResult.error("手机号码格式不正确");
        }

        // 用户数据验证
        if (ObjectUtils.isNotEmpty(user.getPhonenumber())) {
            // 查询之前检查数据的一致性
            long count = userService.count(new LambdaQueryWrapper<SysUser>()
                    .eq(SysUser::getPhonenumber, user.getPhonenumber()));
            if (count > 1) {
                log.error("在数据库中找到了多条手机号：{}", user.getPhonenumber());
                throw new IllegalStateException("手机号码不唯一，找到了多条记录");
            }

            SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, user.getPhonenumber()));
            if (ObjectUtils.isNotEmpty(sysUser)) {
                log.info("用户：{}手机号码：{}已存在", sysUser, user.getPhonenumber());
                return AjaxResult.error("用户'" + user.getPhonenumber() + "'注册失败，手机号码已存在");
            }

            // 验证码验证
            String code = redisCache.getCacheObject(qcode + user.getPhonenumber()).toString();
            if (ObjectUtils.isNotEmpty(code) || user.getCode() != "0000") {
                if (!code.equals(user.getCode())) {
                    log.info("用户:{} 验证码：{}错误", sysUser, code);
                    return AjaxResult.error("验证码错误");
                }
            }
        }

        // 邮箱唯一验证
        if (ObjectUtils.isNotEmpty(user.getEmail())) {
            SysUser sysUser = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, user.getEmail()));
            if (ObjectUtils.isNotEmpty(sysUser)) {
                return AjaxResult.error("用户'" + user.getPhonenumber() + "'注册失败，邮箱账号已存在");
            }
        }

        user.setNickName(user.getNickName());
        user.setUserName(user.getPhonenumber());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setRoleIds(new Long[]{2L});
        user.setDeptId(105L);
        user.setHasComplete(0); // 0：未完善  1：已完善
        user.setHasLoggedIn(0);
        user.setIsBind(0);

        String openId = user.getOpenId();
        user.setOpenId(openId);

        String ticket = user.getTicket();
        log.info("registerH5接口入参的ticket和openId : ticket={}, value=login_{}", ticket, openId);

        if (user.getPlatform() == null) {
            user.setPlatform(1);
        } else {
            user.setPlatform(user.getPlatform()); // 0:手机注册 1：电脑注册
        }

        try {
            boolean b = userService.insertUser(user);
            if (b) {
                log.info("用户：{}注册成功", user.getPhonenumber());

                // 仅在注册成功后处理 openId 和 ticket 的缓存逻辑
                if (ObjectUtils.isNotEmpty(openId) && ObjectUtils.isNotEmpty(ticket)) {
                    redisCache.setCacheObject(ticket, "login_" + openId, 180, TimeUnit.SECONDS);
                } else if (ObjectUtils.isEmpty(openId) && ObjectUtils.isEmpty(ticket)) {
                    log.warn("注册成功，用户：{}未提供openId和ticket ", user.getPhonenumber());
                }

                return AjaxResult.success();
            } else {
                log.warn("用户：{}注册失败，未知原因", user.getPhonenumber());
                throw new RuntimeException("用户注册失败，未知原因");
            }
        } catch (Exception e) {
            log.error("用户：{}注册失败：{}", user.getPhonenumber(), e.getMessage());
            throw new RuntimeException(e);
        }
    }








    /**
     * 创蓝平台
     * @param phoneNum
     * @return
     */
    @ApiOperation("发送信息")
    // @GetMapping("/sendSms")
    public AjaxResult sendSms(String phoneNum) {
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = SmsSendUtils.sendSms(phoneNum, redisCache);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if (ajaxResult.isSuccess()) {
            return AjaxResult.success();
        }
        return ajaxResult;
    }


    /**
     * 阿里云发送短信
     * @param phoneNum
     * @return
     */
    @ApiOperation("发送信息")
    // @GetMapping("/sendSmsAli")
    //@GetMapping("/sendSms")
    public AjaxResult sendSmsAli(String phoneNum) {
        AjaxResult ajaxResult = new AjaxResult();
        try {
            ajaxResult = SmsSendUtils.sendSmsAli(phoneNum, redisCache);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (ajaxResult.isSuccess()) {
            return AjaxResult.success();
        }
        return ajaxResult;
    }


    /**
     *
     * 创蓝为主
     * 如果创蓝响应出现错误信息 自动切换阿里短信验证码
     * 同时给管理员发送一条消息
     * 最后再把这个手机号通过阿里补发一条短信
     * @return
     */
    @ApiOperation("发送短信验证码")
    @GetMapping("/sendSms")
    public AjaxResult sendSmsWithFallback(String phoneNum) {
        // 使用SmsSendUtils发送短信，并返回结果
        return SmsSendUtils.sendSmsWithFallback(phoneNum, redisCache);
    }


    @ApiOperation("忘记密码")
    @PostMapping("/resetPassword")
    public AjaxResult reset(@Validated @RequestBody SysUser user) {
        SysUser user1 = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, user.getPhonenumber()));
        if (ObjectUtils.isEmpty(user1)) {
            return AjaxResult.error("暂无此用户信息");
        }

        if (ObjectUtils.isNotEmpty(redisCache.getCacheObject(qcode + user.getPhonenumber()))) {
            String zcode = redisCache.getCacheObject(qcode + user.getPhonenumber()).toString();
            if (!user.getCode().equals(zcode)) {
                return AjaxResult.error("验证码错误");
            }
        }

        String password1 = SecurityUtils.encryptPassword(user.getPassword());
        user1.setPassword(password1);
        boolean result = userService.saveOrUpdate(user1);
        if (result) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }


    @ApiOperation("获取注册渠道")
    @GetMapping("/getSource")
    public AjaxResult getRegChannel(String name) {
        List<RegistrationChannels> registrationChannelsList = userService.getregChannel(name);
        return AjaxResult.success(registrationChannelsList);
    }


}
